use mio::event::Source;
pub(crate) use mio::net::TcpListener as MioTcpListener;
pub(crate) use std::net::TcpListener as StdTcpListener;
use std::{fmt, io, net::SocketAddr as StdSocketAddr};

pub(crate) enum MioListener {
    Tcp(MioTcpListener),
    #[cfg(unix)]
    Uds(MioUnixListener),
}

impl MioListener {
    pub(crate) fn local_addr(&self) -> SocketAddr {
        match *self {
            MioListener::Tcp(ref lst) => lst
                .local_addr()
                .map(SocketAddr::Tcp)
                .unwrap_or(SocketAddr::Unknown),
        }
    }
    pub(crate) fn accept(&self) -> io::Result<MioStream> {
        //因为 self 是一个引用，而你需要匹配的是引用指向的具体值。所以需要使用 *self 来解引用，以便正确匹配 MioListener 的变体。
        match *self {
            MioListener::Tcp(ref lst) => lst.accept().map(|(stream, _)| MioStream::Tcp(stream)),
        }
    }
}

impl Source for MioListener {
    fn register(
        &mut self,
        registry: &mio::Registry,
        token: mio::Token,
        interests: mio::Interest,
    ) -> std::io::Result<()> {
        todo!()
    }

    fn reregister(
        &mut self,
        registry: &mio::Registry,
        token: mio::Token,
        interests: mio::Interest,
    ) -> std::io::Result<()> {
        todo!()
    }

    fn deregister(&mut self, registry: &mio::Registry) -> std::io::Result<()> {
        todo!()
    }
}

impl From<StdTcpListener> for MioListener {
    fn from(lst: StdTcpListener) -> Self {
        MioListener::Tcp(MioTcpListener::from_std(lst))
    }
}

pub(crate) enum SocketAddr {
    Unknown,
    Tcp(StdSocketAddr),
}

impl fmt::Display for SocketAddr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            Self::Unknown => write!(f, "Unknown SocketAddr"),
            Self::Tcp(ref addr) => write!(f, "{}", addr),
        }
    }
}

pub enum MioStream {
    Tcp(mio::net::TcpStream),
}
